package com.smartfactory.sail.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smartfactory.sail.dto.InspectioncriteriaDto;
import com.smartfactory.sail.dto.ItemMaterialDto;
import com.smartfactory.sail.dto.ItemMaterialInfoDto;
import com.smartfactory.sail.dto.ItemWorkingprocedureDto;
import com.smartfactory.sail.entity.*;
import com.smartfactory.sail.entity.enums.ItemStatusEnum;
import com.smartfactory.sail.entity.enums.StorageType;
import com.smartfactory.sail.mapper.ItemMapper;
import com.smartfactory.sail.mapper.ItemMaterialMapper;
import com.smartfactory.sail.service.*;
import com.smartfactory.sail.utils.PageUtils;
import com.smartfactory.sail.vo.PageParam;
import com.smartfactory.sail.vo.item.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 物料表,生产原料,原料,产品表 服务实现类
 * </p>
 *
 * @author 王巨壁
 * @since 2019-07-24
 */
@Service
public class ItemServiceImpl extends ServiceImpl<ItemMapper, Item> implements IItemService {

    private IItemInspectioncriteriaService iItemInspectioncriteriaService;
    private IItemMaterialService iItemMaterialService;
    private IItemWorkingprocedureService itemWorkingprocedureService;
    private ItemMapper itemMapper;
    private ItemMaterialMapper itemMaterialMapper;
    private IStorageCurrentInfoService iStorageCurrentInfoService;

    public ItemServiceImpl(IItemInspectioncriteriaService iItemInspectioncriteriaService, IItemMaterialService iItemMaterialService, IItemWorkingprocedureService itemWorkingprocedureService, ItemMapper itemMapper, ItemMaterialMapper itemMaterialMapper, IStorageCurrentInfoService iStorageCurrentInfoService) {
        this.iItemInspectioncriteriaService = iItemInspectioncriteriaService;
        this.iItemMaterialService = iItemMaterialService;
        this.itemWorkingprocedureService = itemWorkingprocedureService;
        this.itemMapper = itemMapper;
        this.itemMaterialMapper = itemMaterialMapper;
        this.iStorageCurrentInfoService = iStorageCurrentInfoService;
    }

    //itemmode = 1 是产品
    private static final Integer ITEMMODE_PROJECT = 1;
    //itemmode = 2 是原料
    private static final Integer ITEMMODE_MATERIAL = 2;

    @Transactional
    @Override
    public Long addProduct(AddProjectReq req, ItemStatusEnum status) {

        //保存产品基本信息
        Item item = new Item();
        BeanUtils.copyProperties(req, item);
        item.setItemMode(ITEMMODE_PROJECT);
        item.setStatus(status);//在产
        if (!this.save(item)) {
            return -1L;
        }

        Long productId = item.getId();

        List<ItemMaterial> itemMaterials = new ArrayList<>();
        //保存产品原料信息
        List<ItemMaterialDto> itemMaterialList = req.getItemMaterialList();
        for (ItemMaterialDto itemMaterialDto : itemMaterialList) {
            ItemMaterial itemMaterial = new ItemMaterial();
            BeanUtils.copyProperties(itemMaterialDto, itemMaterial);
            itemMaterial.setProductId(productId);
            itemMaterials.add(itemMaterial);
        }
        iItemMaterialService.saveBatch(itemMaterials);

        //保存产品的入库检验标准
        List<ItemInspectioncriteria> inspectionCriterias = new ArrayList<>();
        List<InspectioncriteriaDto> inspectioncriteriaList = req.getInspectioncriteriaList();
        for (InspectioncriteriaDto inspectioncriteriaDto : inspectioncriteriaList) {
            ItemInspectioncriteria itemInspectioncriteria = new ItemInspectioncriteria();
            BeanUtils.copyProperties(inspectioncriteriaDto, itemInspectioncriteria);
            itemInspectioncriteria.setItemId(productId);
            inspectionCriterias.add(itemInspectioncriteria);
        }
        iItemInspectioncriteriaService.saveBatch(inspectionCriterias);

        //保存产品的流程和流程检验标准
        List<ItemWorkingprocedureDto> workingprocedureList = req.getWorkingprocedureList();
        ArrayList<ItemWorkingprocedure> itemWorkingprocedures = new ArrayList<>();
        for (int i = 0; i < workingprocedureList.size(); i++) {
            ItemWorkingprocedure workingprocedure = new ItemWorkingprocedure();
            workingprocedure.setDept(req.getDeptId());//设置流程对应的部门信息
            BeanUtils.copyProperties(workingprocedureList.get(i), workingprocedure);
            workingprocedure.setSort(i);
            workingprocedure.setItemId(productId);
            itemWorkingprocedures.add(workingprocedure);
        }
        itemWorkingprocedureService.saveBatch(itemWorkingprocedures);

        StorageCurrentInfo storageCurrentInfo = new StorageCurrentInfo();
        storageCurrentInfo.setItemId(item.getId());
        storageCurrentInfo.setStorageType(StorageType.CPK);
        iStorageCurrentInfoService.save(storageCurrentInfo);

        return productId;
    }

    @Override
    public Long addMaterial(AddMaterialReq req) {
        //保存原料基本信息
        Item item = new Item();
        BeanUtils.copyProperties(req, item);
        item.setItemMode(ITEMMODE_MATERIAL);
        item.setStatus(ItemStatusEnum.ZC);//在产
        if (this.save(item)) {
            ArrayList<ItemInspectioncriteria> list = new ArrayList<>();
            List<InspectioncriteriaDto> inspectioncriteriaList = req.getInspectioncriteriaList();
            for (InspectioncriteriaDto c : inspectioncriteriaList) {
                ItemInspectioncriteria itemInspectioncriteria = new ItemInspectioncriteria();
                BeanUtils.copyProperties(c, itemInspectioncriteria);
                itemInspectioncriteria.setItemId(item.getId());
                list.add(itemInspectioncriteria);
            }
            iItemInspectioncriteriaService.saveBatch(list);
            StorageCurrentInfo storageCurrentInfo = new StorageCurrentInfo();
            storageCurrentInfo.setItemId(item.getId());
            storageCurrentInfo.setStorageType(StorageType.YLK);
            iStorageCurrentInfoService.save(storageCurrentInfo);
            return item.getId();
        }
        return -1L;
    }

    @Override
    public IPage<ListItemResp> listItem(Map<String, Object> queryParam, PageParam pageParam) {
        Page<ListItemResp> page = new Page<>();
        PageUtils.createPage(page, pageParam);
        QueryWrapper<Map<String, Object>> query = new QueryWrapper<>();
        query.allEq(queryParam);
        page.setAsc("status");
        IPage<ListItemResp> listPage = itemMapper.getListPage(page, query);
        return listPage;
    }

    /**
     * 获取原料列表
     *
     * @param queryParam
     * @param pageParam
     * @return
     */
    @Override
    public IPage<ListMaterialResp> listMaterials(Map<String, Object> queryParam, PageParam pageParam) {
        Page<ListMaterialResp> page = new Page<>();
        PageUtils.createPage(page, pageParam);
        QueryWrapper<Map<String, Object>> query = new QueryWrapper<>();
        query.allEq(queryParam);
        return itemMapper.listMaterials(page, query);
    }

    @Override
    public ProjectInfoResp getProductInfoById(Long id) {

        Item item = this.getById(id);
        if (null == item)
            return null;
        ProjectInfoResp result = new ProjectInfoResp();
        BeanUtils.copyProperties(item, result);

        //根据itemId获取检验标准
        QueryWrapper<ItemInspectioncriteria> itemInspectioncriteriaQueryWrapper = new QueryWrapper<>();
        itemInspectioncriteriaQueryWrapper.eq("itemId", id).orderByAsc("updateTime");
        List<ItemInspectioncriteria> list = iItemInspectioncriteriaService.list(itemInspectioncriteriaQueryWrapper);
        ArrayList<InspectioncriteriaDto> inspectioncriteriaDtos = new ArrayList<>();
        for (ItemInspectioncriteria itemInspectioncriteria : list) {
            InspectioncriteriaDto inspectioncriteriaDto = new InspectioncriteriaDto();
            BeanUtils.copyProperties(itemInspectioncriteria, inspectioncriteriaDto);
            inspectioncriteriaDtos.add(inspectioncriteriaDto);
        }
        //设置检验标准
        result.setInspectioncriteriaList(inspectioncriteriaDtos);

        //获取产品所需原料
        List<ItemMaterialInfoDto> materialListByProductId = itemMaterialMapper.getMaterialListByProductId(id);
        result.setItemMaterialList(materialListByProductId);

        QueryWrapper<ItemWorkingprocedure> itemWorkingprocedureQueryWrapper = new QueryWrapper<>();
        itemWorkingprocedureQueryWrapper.eq("itemId", id).orderByAsc("sort");
        List<ItemWorkingprocedure> works = itemWorkingprocedureService.list(itemWorkingprocedureQueryWrapper);
        List<ItemWorkingprocedureDto> workDtos = new ArrayList<>();
        for (ItemWorkingprocedure work : works) {
            ItemWorkingprocedureDto workDto = new ItemWorkingprocedureDto();
            BeanUtils.copyProperties(work, workDto);
            workDtos.add(workDto);
        }
        result.setWorkingprocedureList(workDtos);
        result.setDeptId(works.get(0).getDept());

        return result;
    }

    @Override
    public Boolean updateProductStatus(Long itemId, String status) {
        Item item = new Item();
        item.setId(itemId);
        boolean flag = false;
        for (ItemStatusEnum value : ItemStatusEnum.values()) {
            if (value.getDescp().equals(status)) {
                flag = true;
                item.setStatus(value);
                break;
            }
        }
        if (!flag) {
            return false;
        }
        return updateById(item);
    }

    @Override
    public Dept getDeptByItemId(Long itemId) {

        return itemMapper.getDeptByItemId(itemId).get(0);
    }
}
